﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace ORMTool
{
    public static class XMLService
    {
        public static T Get<T>(string path, string name = "Item")
        {
            try
            {
                T model = default(T);
                if (!File.Exists(path))
                    return model;
                XElement xdoc = XElement.Load(path);
                PropertyInfo[] myPropertyInfo = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
                model = Activator.CreateInstance<T>();
                XElement item = xdoc.Elements(name).FirstOrDefault();
                if (item == null) return model;
                foreach (var prop in myPropertyInfo)
                {
                    Type colType = prop.PropertyType;
                    if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                        colType = colType.GetGenericArguments()[0];
                    if (item.Element(prop.Name) == null) continue;
                    object itemValue = item.Element(prop.Name).Value;
                    if (prop != null && prop.CanWrite)
                    {
                        if (itemValue == null || string.IsNullOrEmpty(itemValue.ToString()) || Convert.IsDBNull(itemValue))
                        {
                            prop.SetValue(model, null, null);
                        }
                        else
                        {
                            if (colType.IsEnum)
                            {
                                int flag = 0;
                                int.TryParse(itemValue.ToString(), out flag);
                            }
                            else
                            {
                                var value = Convert.ChangeType(itemValue, colType);
                                prop.SetValue(model, value, null);
                            }
                        }
                    }
                }
                return model;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        public static void Save<T>(T item, string path, string name = "Item")
        {
            try
            {
                XDocument xdoc;
                bool isNew = !File.Exists(path);
                if (isNew)
                    xdoc = new XDocument(new XElement("Root"));
                else
                    xdoc = XDocument.Load(path);
                XElement xeleRoot = xdoc.Root;
                xeleRoot.RemoveAll();
                PropertyInfo[] myPropertyInfo = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
                if (item != null)
                {
                    XElement xeleItem = new XElement(name);
                    for (int i = 0; i < myPropertyInfo.Length; i++)
                    {
                        PropertyInfo pi = myPropertyInfo[i];
                        xeleItem.SetElementValue(pi.Name,
                            pi.GetValue(item, null) == null ? DBNull.Value : pi.GetValue(item, null));
                    }
                    xeleRoot.Add(xeleItem);
                }
                xdoc.Save(path);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        public static void CreateXML(string path)
        {
            try
            {
                XDocument xdoc;
                bool isNew = !File.Exists(path);
                if (isNew)
                    xdoc = new XDocument(new XElement("Root"));
                else
                    return;
                xdoc.Save(path);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
    }
}
